package cn.ai.shoes.client.service.impl;

import cn.ai.shoes.client.entity.*;
import cn.ai.shoes.client.entity.modelvo.*;
import cn.ai.shoes.client.service.*;
import cn.ai.shoes.client.entity.vo.ComfyuiReturnVo;

import cn.ai.shoes.client.utils.ComfyuiServerUtil;
import cn.ai.shoes.client.utils.ComfyuiSmallUtils;
import cn.ai.shoes.client.utils.ImageUtils;
import cn.ai.shoes.common.exception.ServiceException;
import cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants;
import cn.hutool.core.bean.BeanUtil;


import jakarta.annotation.Resource;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static cn.ai.shoes.client.utils.ImageUtils.getRandom;
import static cn.ai.shoes.client.utils.ImageUtils.maskStrUtil;
import static cn.ai.shoes.common.constant.TemplateConstants.*;


@Service
@Slf4j
public class ImageServiceImpl implements ImageService {
    public static final long REDUCTIONRATE = 10L;
    public static final int NOMASK = 0;
    public static final int MAJORMASK = 1;
    public static final int MINORMASK = 2;
    public static final int DOUBLEMAKS = 3;
    public static final String EMPLY = "";
    public static final String MAJOR_TYPE = "主图";
    public static final String MINOR_TYPE = "附图";
    @Resource
    private CurrentServerEntity currentServerEntity;
    @Resource
    private ImageUtils imageUtils;
    @Resource
    private ComfyuiServerUtil comfyuiServiceUtil;
    /**
     * 请求comfyui返回最终结果
     * @param pi
     * @return
     */
    @Override
    public ComfyuiReturnVo requestByPromptId(String pi,String server) throws Exception {
        String url = comfyuiServiceUtil.getUrlByKey(server);
        ComfyuiReturnVo comfyuiReturnVo = imageUtils.comfyuiImageUtilV2(pi, url);
        return comfyuiReturnVo;
    }
    /**
     * 抠图
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask ktImage(KtModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图
        ComfyuiUploadLog imageComfyuiUploadLog = getComfyuiUploadLog(vo.getImageId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiModel comfyuiModel = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setImage(imageComfyuiUploadLog.getName());
        return getComfyuiTask(KT_FTLH, comfyuiModel,currentServerUrl);
    }

    /**
     * 图加图无锁
     * @param vo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask tjtwsImage(TjtwsModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图和附图的日志信息
        ComfyuiUploadLog majorComfyuiUploadLog = getComfyuiUploadLog(vo.getMajorId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiUploadLog minorComfyuiUploadLog = getComfyuiUploadLog(vo.getMinorId(), currentServerUrl, MINOR_TYPE);
        // 3. 构建发送到ComfyUI的模型参数
        ComfyuiModel comfyuiModel = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setMajorStrength(getRandom(vo.getMajorStrength() / REDUCTIONRATE))
                .setMinorStrength(vo.getMinorStrength() / REDUCTIONRATE)
                .setLoreName(ComfyuiSmallUtils.getLoreName(vo))
                .setMajorImage(majorComfyuiUploadLog.getName())
                .setMinorImage(minorComfyuiUploadLog.getName());
        return getComfyuiTask(TJTWS_FTLH, comfyuiModel,currentServerUrl);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask strhzxsImage(StrhzxsModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图和附图的日志信息
        ComfyuiUploadLog majorComfyuiUploadLog = getComfyuiUploadLog(vo.getMajorId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiUploadLog minorComfyuiUploadLog = getComfyuiUploadLog(vo.getMinorId(), currentServerUrl, MINOR_TYPE);
        // 3. 构建发送到ComfyUI的模型参数
        ComfyuiModel comfyuiModel = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setMajorImage(majorComfyuiUploadLog.getName())
                .setMinorImage(minorComfyuiUploadLog.getName())
                .setLoreName(ComfyuiSmallUtils.getLoreName(vo))
                .setMajorStrength(getRandom(vo.getMajorStrength() / REDUCTIONRATE))
                .setMinorStrength(0.5 + (vo.getMinorStrength() * 0.05))
                .setStructuralStrength(0.3 + (vo.getStructuralStrength() * 0.05));
        return getComfyuiTask("strhzxs2.ftlh", comfyuiModel,currentServerUrl);
    }


    /**
     * 图加图OK
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask tjtokImage(TstokModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图
        ComfyuiUploadLog imageComfyuiUploadLog = getComfyuiUploadLog(vo.getImageId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiModel comfyuiModel = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setImage(imageComfyuiUploadLog.getName())
                .setLoreName(ComfyuiSmallUtils.getLoreName(vo))
                .setDenoise(getRandom(0.4f + (vo.getDenoise() * 0.05f)));
        return getComfyuiTask(TSTOK_FTLH, comfyuiModel,currentServerUrl);
    }

    /**
     * Lore文生图
     * @param vo
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask lorewstImage(LorewstModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        ComfyuiModel comfyuiModel = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setLoreName(ComfyuiSmallUtils.getLoreName(vo))
                .setPrompt(vo.getPrompt());
        // .setDenoise(vo.getDenoise() * 0.1f);
        return getComfyuiTask(LOREWST_FTLH, comfyuiModel,currentServerUrl);
    }

    /**
     * 高清放大
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask gqfdImage(GqfdModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图
        ComfyuiUploadLog imageComfyuiUploadLog = getComfyuiUploadLog(vo.getImageId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiModel comfyuiModel = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setImage(imageComfyuiUploadLog.getName());
        return getComfyuiTask(GQFD_FTLH, comfyuiModel,currentServerUrl);
    }

    /**
     * 鞋底互换（蒙版）
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask xdhhImage(XdhhModelVo vo) throws Exception {
        ComfyuiModel comfyuiModel = new ComfyuiModel();
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图
        ComfyuiUploadLog majarComfyuiUploadLog = getComfyuiUploadLog(vo.getMajorId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiUploadLog minorComfyuiUploadLog = getComfyuiUploadLog(vo.getMinorId(), currentServerUrl, MINOR_TYPE);
        // "图片蒙蔽状态{0:不蒙蔽,1:蒙蔽鞋面图,2:蒙蔽鞋底图,3:蒙蔽两图}"
        String majorImageName = majarComfyuiUploadLog.getName();
        String minorImageName = minorComfyuiUploadLog.getName();
        if (vo.getMaskStates() == NOMASK) {
            comfyuiModel.setMajorImage(majorImageName)
                    .setMinorImage(minorImageName);
        } else if (vo.getMaskStates() == MAJORMASK) {
            comfyuiModel.setMajorImage(maskStrUtil(majorImageName))
                    .setMinorImage(minorImageName);
        } else if (vo.getMaskStates() == MINORMASK) {
            comfyuiModel.setMajorImage(majorImageName)
                    .setMinorImage(maskStrUtil(minorImageName));
        } else if (vo.getMaskStates() == DOUBLEMAKS) {
            comfyuiModel.setMajorImage(maskStrUtil(majorImageName))
                    .setMinorImage(maskStrUtil(minorImageName));
        }
        return getComfyuiTask(XDHH_FTLH, comfyuiModel,currentServerUrl);
    }

    /**
     * 局部重绘（蒙版）
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask jbchImage(JbchModelVo vo) throws Exception {
        ComfyuiModel comfyuiModel = new ComfyuiModel();
        String currentServerUrl = currentServerUrl();
        // "图片蒙蔽状态{0:不蒙蔽,1:蒙蔽鞋面图,2:蒙蔽鞋底图,3:蒙蔽两图}"
        // 1. 获取主图
        ComfyuiUploadLog majarComfyuiUploadLog = getComfyuiUploadLog(vo.getMajorId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiUploadLog minorComfyuiUploadLog = getComfyuiUploadLog(vo.getMinorId(), currentServerUrl, MINOR_TYPE);
        // "图片蒙蔽状态{0:不蒙蔽,1:蒙蔽鞋面图,2:蒙蔽鞋底图,3:蒙蔽两图}"
        String majorImageName = majarComfyuiUploadLog.getName();
        String minorImageName = minorComfyuiUploadLog.getName();
        BeanUtil.copyProperties(vo, comfyuiModel);
        if (vo.getIsMask() == MAJORMASK) {
            comfyuiModel.setMajorImage(maskStrUtil(majorImageName))
                    .setMinorImage(majorImageName)
                    .setPrompt(vo.getPrompt());
        } else if (vo.getIsMask() == MINORMASK) {
            comfyuiModel.setMajorImage(maskStrUtil(minorImageName))
                    .setMinorImage(maskStrUtil(minorImageName))
                    .setPrompt(EMPLY);
        } else {
            throw new ServiceException(GlobalErrorCodeConstants.COMFYUI_FAILED_SAVE_IMAGE.getResult());
        }
        return getComfyuiTask(JBCH_FTLH, comfyuiModel,currentServerUrl);
    }

    /**
     * 消除（蒙版）
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask xcImage(XcModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图
        ComfyuiUploadLog imageComfyuiUploadLog = getComfyuiUploadLog(vo.getImageId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiModel modelBean = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setImage(maskStrUtil(imageComfyuiUploadLog.getName()));
        return getComfyuiTask(XC_FTLH, modelBean,currentServerUrl);
    }
    /**
     * 修复（蒙版）
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiTask xfImage(XfModelVo vo) throws Exception {
        String currentServerUrl = currentServerUrl();
        // 1. 获取主图
        ComfyuiUploadLog imageComfyuiUploadLog = getComfyuiUploadLog(vo.getImageId(), currentServerUrl, MAJOR_TYPE);
        ComfyuiModel modelBean = BeanUtil.toBean(vo, ComfyuiModel.class)
                .setImage(maskStrUtil(imageComfyuiUploadLog.getName()));
        return getComfyuiTask(XF_FTLH, modelBean,currentServerUrl);
    }


    /**
     * 执行器
     * @param templateName
     * @param comfyuiModel
     * @return
     */
    private ComfyuiTask getComfyuiTask(String templateName, ComfyuiModel comfyuiModel,String currentServerUrl) throws Exception {
        String pi = imageUtils.createComfyuiTask(comfyuiModel, templateName, currentServerUrl);
        //获取当前服务器地址
        String serverName = comfyuiServiceUtil.getKeyByUrl(currentServerUrl);
        ComfyuiTask task = new ComfyuiTask(pi, serverName);
        return task;
    }

    /**
     * 获取主图的日志信息
     * @param imageId
     * @param currentServerUrl
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ComfyuiUploadLog getComfyuiUploadLog(Integer imageId, String currentServerUrl, String imageType) {
        //判断currentServerUrl是否为空或者是否为0
        if (StringUtil.isEmpty(currentServerUrl)) {
            throw new ServiceException(GlobalErrorCodeConstants.COMFYUI_SERVER_URL_ERROR.getCode(), "ComfyUI服务器地址不能为空");
        }
        //打印
        log.info("\n[currentServerUrl]:当前生成图片的服务器为" + currentServerUrl);
        OssUploadLog majorOssUploadLog = imageUtils.selectOssUploadLogById(imageId, imageType);
        ComfyuiUploadLog majorComfyuiUploadLog = imageUtils.handleImageUpload(majorOssUploadLog, currentServerUrl);
        return majorComfyuiUploadLog;
    }

    /**
     * 获取当前服务的URL
     * @return
     */
    private String currentServerUrl() {
        String currentServerUrl = currentServerEntity.getUrl();
        return currentServerUrl;
    }

}
